#pragma once

/**
 * 1. Channel:对描述符的监控事件管理
 * 2. 关于事件的运算：
 * |：按位或操作将对应的位设为1
 * &：按位与操作检查特定位是否为1
 *
 * 对监控事件的管理 and 对事件触发后的处理(回调)
 */

#include "EventLoop.hpp"
#include "Logger.h"

#include <sys/epoll.h>
#include <functional>

namespace devem {

using callback = std::function<void(void)>;
// class EventLoop;

class Channel {
public:
    Channel(int fd, EventLoop* loop) : fd_(fd), loop_(loop) {}

    int Fd() const { return fd_; }

    uint16_t Events() { return events_; }

    void SetRevents(uint16_t revents) { revents_ = revents; }

    // 设置回调函数
    void SetReadCallBack(callback read_callback) {
        read_callback_ = read_callback;
        UpdateEvent();
    }
    void SetWriteCallBack(callback write_callback) { write_callback_ = write_callback; }
    void SetErrorCallBack(callback error_callback) { error_callback_ = error_callback; }

    // 是否可读/写
    bool ReadAble() { return events_ & EPOLLIN; }
    bool WriteAble() { return events_ & EPOLLOUT; }

    // 开启可读/写
    bool EnableRead() { return events_ |= EPOLLIN; }
    bool EnableWrite() { return events_ |= EPOLLOUT; }

    // 关闭可读/写/全部
    bool DisableRead() { return events_ &= ~EPOLLIN; }
    bool DisableWrite() { return events_ &= ~EPOLLOUT; }
    bool DisableAll() { return events_ = 0; }

    // update///
    void UpdateEvent() { loop_->UpdateEvent(this); }

    void RemoveEvent() { loop_->RemoveEvent(this); }

    void HandleEvent();

    ~Channel() {
        if (fd_) {
            close(fd_);
        }
    }

private:
    int fd_;
    EventLoop* loop_;
    uint16_t events_;
    uint16_t revents_;
    callback read_callback_;
    callback write_callback_;
    callback error_callback_;
    // other callbacks...
};
}  // namespace devem
